package com.example.cscot.ui.dialog;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import com.example.cscot.LewayHelper;
import com.example.cscot.LewayTimer;
import com.example.cscot.R;
import com.example.cscot.RtCallback;
import com.example.cscot.WeiLe;
import com.example.cscot.databinding.FragmentDialogBinding;

import org.json.JSONArray;

public class DialogFragment extends Fragment {
    //
    private FragmentDialogBinding binding;
    public TextView mTvFull;
    public EditText mEtSay;
    public String mNotShown = "";
    public long mLastCtms = 0;
    public Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // 消息缺省就在UI线程执行的
            Bundle bundle = msg.getData();
            String str = bundle.getString("ChangeUI");
            WeiLe.gLogText += LewayHelper.logLine("handleMessage: ui " + str);
            mTvFull.setMaxWidth(mTvFull.getWidth());
            mTvFull.append(str);    // 按理应该说是每2秒钟会多显示一点东西的，实际好像不是，有点怪
            LewayHelper.scrollToEnd(mTvFull);
        }
    };
    //
    // gFullText保存的是对话记录，gLogText是调试日志
    // 调试程序时，特别没有上线前，这个机制一定要保留，对于促进开发非常有用，看看日志，看是否按你预期在工作
    //
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentDialogBinding.inflate(inflater, container, false);
        View root = binding.getRoot();
        //
        mEtSay = root.findViewById(R.id.etSay);
        mTvFull = root.findViewById(R.id.tvFull);
        mTvFull.setText(WeiLe.gFullText);
        mTvFull.setMovementMethod(ScrollingMovementMethod.getInstance());
        mEtSay.setMovementMethod(ScrollingMovementMethod.getInstance());

        // first button
        Button myButton = root.findViewById(R.id.btnDebug); // 看调试信息，确认是否按预期在工作
        myButton.setOnClickListener(v -> {
            // 在这里处理按钮的点击事件
            String txtFull = mTvFull.getText().toString();
            if (!txtFull.contains("os.arch=") && !WeiLe.gFullText.isEmpty()) {
                WeiLe.gFullText = mTvFull.getText().toString();
                // 上回显示的对话信息，保存起来
                // 调试信息不用保存，一直在全局变量gLogText里
            }
            mTvFull.setText(WeiLe.gLogText);
            LewayHelper.scrollToEnd(mTvFull);
        });

        // second button
        myButton = root.findViewById(R.id.btnSay);
        myButton.setOnClickListener(v -> {
            if (mNotShown.length() > 0) {
                mTvFull.setMaxWidth(mTvFull.getWidth());
                mTvFull.append(mNotShown);
                LewayHelper.scrollToEnd(mTvFull);
                mNotShown = ""; // 没有显示出来的显示出来，然后清空为后续未显示保存做准备
            }
            // 在这里处理按钮的点击事件
            String txtFull = mTvFull.getText().toString();
            if (!txtFull.contains("os.arch=") && !WeiLe.gFullText.isEmpty()) {
                WeiLe.gFullText = mTvFull.getText().toString(); // 保存起来
            } else {
                mTvFull.setText(WeiLe.gFullText);
                LewayHelper.scrollToEnd(mTvFull);
            }

            if (mEtSay.getText().length() > 1) {
                // talk to LLM
                mTvFull.append("\n我: " + mEtSay.getText().toString());
                mTvFull.append("\n智启费曼: ");
                WeiLe.gLogText += LewayHelper.logLine("ready to postChats");
                JSONArray array = new JSONArray();
                WeiLe.gDialogLlm.postChats(array, mEtSay.getText().toString(), new RtCallback() {
                    @Override
                    public void onRightTime(String strResult) {
                        doCb(strResult);
                    }
                });
                // 问题提交到服务器后，2秒钟定时器后，就会调用这个回调
                LewayTimer lt = new LewayTimer(2000, new RtCallback() {
                    @Override
                    public void onRightTime(String strResult) {
                        WeiLe.mainActivity.runOnUiThread(() -> {
                            if (!mTvFull.getText().toString().isEmpty()) {
                                WeiLe.gFullText = mTvFull.getText().toString();
                                // 此时应该不是调试信息，所以保存起来
                            }
                            mEtSay.setText("");    // Clear上一次的问题，为下一次提问做准备
                        });
                    }
                }, true);
            } else {
                // 给服务端发的问题太短啦，防止不小心误点击我说
                Toast.makeText(WeiLe.mainActivity, "too short", Toast.LENGTH_LONG).show();
                WeiLe.gLogText += LewayHelper.TS() + " too short\n";
            }
            WeiLe.gLogText += LewayHelper.logLine("postChats done");
        });
        return root;
    } // >>> onCreateView

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
    //
    public void doCb(String cbResult) {
        mNotShown += cbResult;
        if ((LewayHelper.CTMS() - mLastCtms) < 2000) {
            if (!(cbResult.contains("。"))) {
                return;
            }
        }
        mLastCtms = LewayHelper.CTMS(); // 至少2秒钟更新一下当前接收到的结果

        // 切换到消息方法
        Message message = new Message();
        Bundle bundle = new Bundle();
        bundle.putString("ChangeUI", mNotShown);
        message.setData(bundle);
        mHandler.sendMessage(message);
        WeiLe.gLogText += LewayHelper.logLine("doCb: thread " + mNotShown);
        mNotShown = "";
        // 这个runOnUiThread()可能需要很长时间集中被调用，不是1/2，1/2间隔，而是1111/2222
        // 调度不是我们想的那样，切换到消息模式看看。
        // WeiLe.mainActivity.runOnUiThread(() -> {
        //     WeiLe.gLogText += LewayHelper.logLine("doCb: ui " + cbResult);
        //     mTvFull.setMaxWidth(mTvFull.getWidth());
        //     mTvFull.append(mNotShown);
        //     LewayHelper.scrollToEnd(mTvFull);
        //     mNotShown = "";
        // });
    } // doCb
} // >>> class DialogFragment
